/*****************************************************************************
	SNEGA UTILITIES 0.7a
	Copyright (C) 2009, Xiaohan Tian (snega0223)
	
	http://code.google.com/p/snega-utilities/
	
	This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License(LGPL) as
	published by the Free Software Foundation, either version 3 of the 
	License, or(at your option) any later version.

	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU Lesser General Public License for more details.
	
	You should have received a copy of the GNU Lesser General Public License
	along with this program.  If not, see <http://www.gnu.org/licenses/>.
*****************************************************************************/

package org.sng.util.web.elmt;

import java.util.ListIterator;

import javax.servlet.http.HttpServletRequest;

import org.sng.util.slog.SLog;
import org.sng.util.var.SString;
import org.sng.util.var.SVoid;

public class NodeContainer extends Node {
	
	public NodeContainer()
	{
		super();
	}
	
	public NodeContainer(int n)
	{
		super(n);
	}
	
	public NodeContainer(String id)
	{
		super();
		
		this.PushProperty("id", id);
	}
	
	/* When create a container, you must append container to its parent first and then append child to it. */
	public NodeContainer Create()
	{
		return new NodeContainer();
	}
	
	public NodeContainer Create(int n)
	{
		return new NodeContainer(n);
	}
	
	public String GetType()
	{
		return "container";
	}
	
	public NodeContainer Create(String id, RuntimeEnvironment re)
	{
		NodeContainer o = new NodeContainer();
		
		o.m_properties.put("id", new SString(id));
		
		String postback = re.GetRequest().getParameter(id + "_postback");
		if (postback != null)
			o.PushProperty("postback", postback);
		
		return o;
	}
	
	public StringBuffer Execute(RuntimeEnvironment re)
	{
		StringBuffer result = new StringBuffer();
		
		try {
			//this.Do(re);
			
			this.AppendPostList(re);
			
			SVoid prop = null;
			
			if ((prop = this.m_properties.get("id")) == null)
			{
				throw new Exception("Critical property \"id\" is missing.");
			}
			
			String sid = prop.GetString(re);
			
			StringBuffer properties = new StringBuffer();
			if ((prop = this.m_properties.get("class")) != null) {
				properties.append(" class=\"");
				properties.append(prop.GetString(re));
				properties.append("\"");
			}
			if ((prop = this.m_properties.get("style")) != null) {
				properties.append(" style=\"");
				properties.append(prop.GetString(re));
				properties.append("\"");
			}
			
			result.append("<div id=\"" + sid + "\"" + properties + ">");
			ListIterator<Node> interator = this.m_children.listIterator();
			
	        while (interator.hasNext())
	        {
	        	result.append(interator.next().Execute(re));
	        }
			result.append("</div>");

		} catch (Exception e) {
			SLog.println("Webpage runtime error on line " + this.m_currLineNumber);
			e.printStackTrace();
		}
		
		return result;
	}
	
	public void AppendPostList(RuntimeEnvironment re)
	{
		String sid = this.m_properties.get("id").GetString(re);
		
		re.AppendPostList("if($(\"" + sid + "\")!=null){");
		re.AppendPostList("para.add(\"cid\", \"" + sid + "\");");
		re.AppendPostList("para.add(\"type\", \"Container\");");
		
		SVoid postback = this.GetProperty("postback");
		if (postback != null)
			re.AppendPostList(sid + "_postback", "\"" + SString.ToStringLiterealSafe(postback.GetString(re)) + "\"");
      
		re.AppendPostList("};");
	}
	
	public NodeContainer ClearChildren(RuntimeEnvironment re)
	{
		this.m_children.clear();
		
		re.AppendJavascript("$(\"" + this.m_properties.get("id").GetString(re) + "\").innerHTML=\"\";");
		
		return this;
	}
	
	public NodeContainer AppendChild(RuntimeEnvironment re, Node o)
	{
		this.AddChild(o);
		
		re.GetRoot().AddNodeToIdMap(re, o);
		re.GetRoot().AddNodeToTypeList(re, o);
		
		re.AppendJavascript("$(\"" + this.m_properties.get("id").GetString(re) + "\").innerHTML+=\"" + SString.ToStringLiterealSafe(o.Execute(re)) + "\";");
		
		return this;
	}
	
	public NodeContainer RemoveChild(RuntimeEnvironment re, String id)
	{
		Node o = null;
		
		ListIterator<Node> interator = this.m_children.listIterator();
		
        while (interator.hasNext())
        {
        	SVoid sid = null;
        	o = interator.next();
        	
        	if ((sid = o.GetProperty("id")) != null) {
        		if (sid.GetString(re).compareTo(id) == 0)
        		{
        			this.RemoveNodeFromTypeList(o.GetType(), o);
        			
        			re.GetRoot().RemoveNodeFromIdMap(sid.GetString(re));
        			re.GetRoot().RemoveNodeFromTypeList(o.GetType(), o);
        			
        			interator.remove();
        			break;
        		}
        	}
        }
        
        re.AppendJavascript("$(\"" + this.GetProperty("id").GetString(re) + "\").removeChild($(\"" + id + "\"));");
		
		return this;
	}
	
	public NodeContainer AppendChildExist(RuntimeEnvironment re, Node o)
	{
		if (o == null)
		{
			return this;
		}
		
		this.AddChild(o);
		
		return this;
	}
	
	public NodeContainer RegisterChildrenInPage(RuntimeEnvironment re)
	{
		String sid = this.m_properties.get("id").GetString(re);
		
		re.AppendPostList("if($(\"" + sid + "\")!=null){");
		
		ListIterator<Node> interator = this.m_children.listIterator();
		
        while (interator.hasNext())
        {
        	Node o = interator.next();
        	
        	SVoid prop = null;
        	
        	if ((prop = o.GetProperty("id")) == null)
        	{
        		continue;
        	}
        	
        	String oid = prop.GetString(re);
        	//SLog.println("para.add(\"" + sid + "_child\", \"" + oid + "\"");
        	if (oid != null)
        	{
        		re.AppendPostList("para.add(\"" + sid + "_child\", \"" + oid + "\");");
        	}
        }
        
        re.AppendPostList("};");
        
		return this;
	}
	
	public NodeContainer RegisterChildren(RuntimeEnvironment re)
	{
		HttpServletRequest request = re.GetRequest();
		String id = this.GetProperty("id").GetString(re);
		
		// Children
		String [] childrenId = request.getParameterValues(id + "_child");
		
		if (childrenId == null)
		{
			return this;
		}
		
		for (int i = 0; i < childrenId.length; i++)
		{
			this.AppendChildExist(re, re.$(childrenId[i]));
		}
		
		return this;
	}
	
	public NodeContainer ShowContainer(RuntimeEnvironment re)
	{
		re.AppendJavascript("showDiv(\"" + this.GetProperty("id").GetString(re) + "\", 0);");
		
		return this;
	}
	
	public NodeContainer HideContainer(RuntimeEnvironment re)
	{
		re.AppendJavascript("hideDiv(\"" + this.GetProperty("id").GetString(re) + "\", 100);");
		
		return this;
	}

}
